﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using Microsoft.Web.Mvc.ModelBinding;

namespace MvcApplicationBindersSample.Binders {
    public class TryParseModelBinder : IExtensibleModelBinder {

        private readonly MethodInfo _tryParseMethod;

        public TryParseModelBinder(MethodInfo tryParseMethod) {
            _tryParseMethod = tryParseMethod;
        }

        public bool BindModel(ControllerContext controllerContext, ExtensibleModelBindingContext bindingContext) {
            // get value from provider
            ValueProviderResult vpResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

            if (vpResult != null) {
                bindingContext.ModelState.SetModelValue(bindingContext.ModelName, vpResult);

                // convert to string, then call TryParse() to convert to appropriate type
                string s = (string)vpResult.ConvertTo(typeof(string));

                // second element will be the result of TryParse()
                object[] invokeParams = new object[] { s, null };
                if ((bool)_tryParseMethod.Invoke(null /* obj */, invokeParams)) {
                    bindingContext.Model = invokeParams[1];
                    return true; // success
                }
                else {
                    bindingContext.ModelState.AddModelError(bindingContext.ModelName,
                        String.Format("Please enter a valid {0}.", bindingContext.ModelType));
                }
            }

            return false; // failure
        }

    }
}
